﻿using System;

namespace Lesson13_继承_里氏替换原则
{
    #region 一 基本概念
    //里氏替换原则是面向对象七大原则中最重要的原则
    //概念：
    //任何父类出现的地方，子类都可以替代
    //重点：
    //语法表现：父类容器装子类对象，因为子类对象包含了父类的所有内容
    //★作用：
    //方便进行对象的存储和管理
    #endregion

    #region 二 实现
    class GameObject
    {
        
    }
    class Player : GameObject
    {
        public void PlayerAtk()
        {
            Console.WriteLine("玩家攻击");
        }
    }
    class Monster : GameObject
    {
        public void MonsterAtk()
        {
            Console.WriteLine("怪物攻击");
        }
    }
    class Boss : GameObject
    {
        public void BossAtk()
        {
            Console.WriteLine("Boss攻击");
        }
    }
    #endregion
    class Program
    {
        static void Main(string[] args)
        {
            #region 二 实现
            GameObject player = new Player();
            GameObject monster = new Monster();
            GameObject boss = new Boss();
            //常用写法
            GameObject[] gameObjects = new GameObject[] { new Player() , new Monster() , new Boss() };

            //现在调用player的PlayerAtk()方法 会报错
            //因为我们使用了Player类的父类GameObject作为容器 装载Player对象 而GameObject不存在PlayerAtk()方法
            //这时我们就需要用到 is 和 as的相关知识

            #endregion

            #region 三 is和as
            //基本概念
            //is：盘算一个对象是否是指定类对象
            //返回一个bool值、
            if (player is Player)
            {
                Console.WriteLine(player is Player);
                Console.WriteLine(player is GameObject);
            }
            //player 不仅是Player类对象 也是GameObject类对象
            //因为在OOP中，子类对象可以被认为是父类的一个实例，因为Player是GameObject的一种特化形式
            if (player is GameObject)
            {
                Console.WriteLine("player是GameObject类对象");
            }

            //as：将一个对象转换为指定类的对象
            Player p = player as Player;
            p.PlayerAtk();      //p作为Player类型 可以调用PlayerAtk()方法

            //如果只是想调用方法 直接使用as转换即可
            (player as Player).PlayerAtk();

            //成功 返回指定类的对象 失败 则返回null
            if (p != null)
            {
                Console.WriteLine("转换成功 p不为null");
            }
            Player p2 = monster as Player;
            if (p2 == null)
            {
                Console.WriteLine("转换失败 p2为null");
            }

            Console.WriteLine("***********************");

            //常用写法
            for (int i = 0; i < gameObjects.Length; i++)
            {
                if (gameObjects[i] is Player)
                {
                    (gameObjects[i] as Player).PlayerAtk();
                }
                else if (gameObjects[i] is Monster)
                {
                    (gameObjects[i] as Monster).MonsterAtk();
                }
                else
                {
                    (gameObjects[i] as Boss).BossAtk();
                }
            }
            #endregion
        }
    }
}
